package com.lxh.cptp.tp;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImpl;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * created by lanxinghua@2dfire.com on 2020/2/25
 * 企业微信第三方，缓存支持
 * 1.suiteAccessToken
 */
public class WxCpTpRedisConfigImpl extends WxCpTpDefaultConfigImpl {
    // suite_ticket与suite_secret配套使用，用于获取suite_access_token 10min
    private static String SUITE_TICKET_KEY = "wx:cptp:suite_ticket";
    // 第三方应用凭证 2h （key按应用区分）
    private static String SUITE_ACCESS_TOKEN_KEY = "wx:cptp:suite_access_token:";
    // H5应用调用企业微信JS接口的临时票据 2h (跟着商家企业Id走)
    private static final String JS_API_TICKET_KEY = "wx:cptp:jsapi_ticket:";


    /**
     * 使用连接池保证线程安全.
     */
    private final JedisPool jedisPool;

    @Override
    public void setSuiteId(String corpId) {
        SUITE_ACCESS_TOKEN_KEY += corpId;
        super.setSuiteId(corpId);
    }

    public WxCpTpRedisConfigImpl(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }



    /**-------------------------- suite ticket -------------------------**/
    @Override
    public String getSuiteTicket() {
        if (isSuiteTicketExpired()){
            String result = "{\"errcode\":40085, \"errmsg\":\"invaild suite ticket\"}";
            System.err.println(result);
            return null;
        }
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.get(SUITE_TICKET_KEY);
        }
    }


    @Override
    public boolean isSuiteTicketExpired() {
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.ttl(SUITE_TICKET_KEY) < 2;
        }
    }

    @Override
    public synchronized void updateSuiteTicket(String suiteTicket, int expiresInSeconds) {
        System.out.println("redis缓存更新成功：" + suiteTicket);
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.setex(SUITE_TICKET_KEY, expiresInSeconds - 200, suiteTicket);
        }
    }

    @Override
    public void expireSuiteTicket() {
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.expire(SUITE_TICKET_KEY, 0);
        }
    }

    /**-------------------------- suite access token -------------------------**/
    @Override
    public String getSuiteAccessToken() {
        if (isSuiteAccessTokenExpired()){
            return null;
        }
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.get(SUITE_ACCESS_TOKEN_KEY);
        }
    }

    @Override
    public boolean isSuiteAccessTokenExpired() {
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.ttl(SUITE_ACCESS_TOKEN_KEY) < 2;
        }
    }

    @Override
    public synchronized void updateSuiteAccessToken(WxAccessToken suiteAccessToken) {
        this.updateSuiteAccessToken(suiteAccessToken.getAccessToken(), suiteAccessToken.getExpiresIn());
    }

    @Override
    public synchronized void updateSuiteAccessToken(String suiteAccessToken, int expiresInSeconds) {
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.setex(SUITE_ACCESS_TOKEN_KEY, expiresInSeconds - 200, suiteAccessToken);
        }
    }

    @Override
    public void expireSuiteAccessToken() {
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.expire(SUITE_ACCESS_TOKEN_KEY, 0);
        }
    }

    /**-------------------------- jsapi ticket -------------------------**/
    public String getJsApiTicket(String authCorpId) {
        System.out.println("缓存中获取jsApiTicket");
        if (isJsApiTicketExpired(authCorpId)){
            return null;
        }
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.get(JS_API_TICKET_KEY + authCorpId);
        }
    }

    public boolean isJsApiTicketExpired(String authCorpId) {
        try (Jedis jedis = this.jedisPool.getResource()) {
            return jedis.ttl(JS_API_TICKET_KEY + authCorpId) < 2;
        }
    }


    // authCorpId 使用第三方企业对应的id
    public synchronized void updateJsApiTicket(String jsApiTicket, int expiresInSeconds, String authCorpId) {
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.setex(JS_API_TICKET_KEY + authCorpId, expiresInSeconds - 200, jsApiTicket);
        }
    }

    public void expireJsApiTicket(String authCorpId) {
        try (Jedis jedis = this.jedisPool.getResource()) {
            jedis.expire(JS_API_TICKET_KEY + authCorpId, 0);
        }
    }

    /**
     * This method will be destroy jedis pool
     */
    public void destroy() {
        this.jedisPool.destroy();
    }
}
